{
public:
Format() = default;
+ Format(const QString& filename) : fname{filename} {}
// Provide virtual public destructor to avoid undefined behavior when
// an object of derived class type is deleted through a pointer to
// its base class type.
virtual ff_type get_type() const = 0;
virtual QVector<ff_cap> get_cap() const = 0;
+ QString fname;
+
protected:
template <class MyFormat>
class RteHdFunctor
static int receiver_must_upper = 1;
static QTextCodec* codec{nullptr};
-static Format* gpx_vec;
+static Vecs::fmtinfo_t gpx_vec;
#define MILITANT_VALID_WAYPT_CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
{
if (setjmp(gdx_jmp_buf)) {
const gdx_info* gi = gdx_get_info();
- gpx_vec = Vecs::Instance().find_vec("gpx").fmt;
+ // FIXME: dynamic not implemented.
+ gpx_vec = Vecs::Instance().find_vec("gpx");
+ Vecs::prepare_format(gpx_vec);
gpx_vec->rd_init(gi->from_device.canon);
} else {
- gpx_vec = nullptr;
+ gpx_vec = Vecs::fmtinfo_t();
rw_init(fname);
}
}
}
}
-void GeoFormat::rd_init(const QString& fname)
-{
- geo_fname = fname;
-}
-
-void GeoFormat::rd_deinit()
-{
- geo_fname.clear();
-}
-
void GeoFormat::read()
{
- gpsbabel::File ifile = gpsbabel::File(geo_fname);
+ gpsbabel::File ifile = gpsbabel::File(fname);
ifile.open(QIODevice::ReadOnly);
QXmlStreamReader reader = QXmlStreamReader(&ifile);
return v;
}
-void GeoFormat::wr_init(const QString& fname)
-{
- geo_fname = fname;
-}
-
-void GeoFormat::wr_deinit()
-{
- geo_fname.clear();
-}
-
void GeoFormat::geo_waypt_pr(const Waypoint* waypointp, QXmlStreamWriter& writer)
{
writer.writeStartElement(QStringLiteral("waypoint"));
void GeoFormat::write()
{
- gpsbabel::File ofile = gpsbabel::File(geo_fname);
+ gpsbabel::File ofile = gpsbabel::File(fname);
ofile.open(QIODevice::WriteOnly | QIODevice::Text);
QXmlStreamWriter writer = QXmlStreamWriter(&ofile);
class GeoFormat : public Format
{
public:
+ using Format::Format;
+
QVector<arglist_t>* get_args() override
{
return &geo_args;
return { (ff_cap)(ff_cap_read | ff_cap_write), ff_cap_none, ff_cap_none };
}
- void rd_init(const QString& fname) override;
+ void rd_init(const QString& fname) override
+ {}
void read() override;
- void rd_deinit() override;
- void wr_init(const QString& fname) override;
+ void wr_init(const QString& fname) override
+ {}
void write() override;
- void wr_deinit() override;
private:
char* deficon = nullptr;
char* nuke_placer{};
- QString geo_fname;
QVector<arglist_t> geo_args = {
{"deficon", &deficon, "Default icon name", nullptr, ARGTYPE_STRING, ARG_NOMINMAX, nullptr },
short_handle mkshort_handle;
};
+static void
+run_reader(Vecs::fmtinfo_t& ivecs, const QString& fname)
+{
+ start_session(ivecs.fmtname, fname);
+ if (ivecs.isDynamic()) {
+ ivecs.fmt = ivecs.factory(fname);
+ Vecs::init_vec(ivecs.fmt);
+ Vecs::prepare_format(ivecs);
+
+ ivecs->rd_init(fname);
+ ivecs->read();
+ ivecs->rd_deinit();
+
+ Vecs::exit_vec(ivecs.fmt);
+ delete ivecs.fmt;
+ ivecs.fmt = nullptr;
+ } else {
+ /* reinitialize xcsv in case two formats that use xcsv were given */
+ Vecs::prepare_format(ivecs);
+
+ ivecs->rd_init(fname);
+ ivecs->read();
+ ivecs->rd_deinit();
+ }
+}
+
+static void
+run_writer(Vecs::fmtinfo_t& ovecs, const QString& ofname)
+{
+ if (ovecs.isDynamic()) {
+ ovecs.fmt = ovecs.factory(ofname);
+ Vecs::init_vec(ovecs.fmt);
+ Vecs::prepare_format(ovecs);
+
+ ovecs->wr_init(ofname);
+ ovecs->write();
+ ovecs->wr_deinit();
+
+ Vecs::exit_vec(ovecs.fmt);
+ delete ovecs.fmt;
+ ovecs.fmt = nullptr;
+ } else {
+ /* reinitialize xcsv in case two formats that use xcsv were given */
+ Vecs::prepare_format(ovecs);
+
+ ovecs->wr_init(ofname);
+ ovecs->write();
+ ovecs->wr_deinit();
+ }
+}
+
static int
run(const char* prog_name)
{
global_opts.masked_objective |= WPTDATAMASK;
}
- start_session(ivecs.fmtname, fname);
- ivecs->rd_init(fname);
- ivecs->read();
- ivecs->rd_deinit();
+ run_reader(ivecs, fname);
did_something = true;
break;
global_opts.masked_objective |= WPTDATAMASK;
}
- ovecs->wr_init(ofname);
- ovecs->write();
- ovecs->wr_deinit();
+ run_writer(ovecs, ofname);
}
break;
global_opts.masked_objective |= WPTDATAMASK;
}
- /* reinitialize xcsv in case two formats that use xcsv were given */
- Vecs::Instance().prepare_format(ivecs);
-
- start_session(ivecs.fmtname, qargs.at(0));
- ivecs->rd_init(qargs.at(0));
- ivecs->read();
- ivecs->rd_deinit();
+ run_reader(ivecs, qargs.at(0));
if (qargs.size() == 2 && ovecs) {
- /* reinitialize xcsv in case two formats that use xcsv were given */
- Vecs::Instance().prepare_format(ovecs);
- ovecs->wr_init(qargs.at(1));
- ovecs->write();
- ovecs->wr_deinit();
+ run_writer(ovecs, qargs.at(1));
}
} else if (!qargs.isEmpty()) {
if (fname.isEmpty()) {
fatal("An input file (-f) must be specified.\n");
}
+
+ if (ivecs.isDynamic()) {
+ ivecs.fmt = ivecs.factory(fname);
+ Vecs::init_vec(ivecs.fmt);
+ }
+ if (ovecs && ovecs.isDynamic()) {
+ ovecs.fmt = ovecs.factory(ofname);
+ Vecs::init_vec(ovecs.fmt);
+ }
+
start_session(ivecs.fmtname, fname);
+ Vecs::prepare_format(ivecs);
ivecs->rd_position_init(fname);
if (global_opts.masked_objective & ~POSNDATAMASK) {
}
if (ovecs) {
+ Vecs::prepare_format(ovecs);
ovecs->wr_position_init(ofname);
}
delete wpt;
}
}
+ Vecs::prepare_format(ivecs);
ivecs->rd_position_deinit();
if (ovecs) {
+ Vecs::prepare_format(ovecs);
ovecs->wr_position_deinit();
}
+
+ if (ovecs && ovecs.isDynamic()) {
+ Vecs::exit_vec(ovecs.fmt);
+ delete ovecs.fmt;
+ ovecs.fmt = nullptr;
+ }
+ if (ivecs.isDynamic()) {
+ Vecs::exit_vec(ivecs.fmt);
+ delete ivecs.fmt;
+ ivecs.fmt = nullptr;
+ }
return 0;
}
--- /dev/null
+51.31177, 12.41318,
+51.31181, 12.41290,
+51.31188, 12.41277,
+51.31216, 12.41226,
+51.31224, 12.41238,
+51.31225, 12.41242,
+51.31229, 12.41249,
+51.31263, 12.41285,
+51.31272, 12.41282,
+51.31281, 12.41274,
+51.31281, 12.41272,
+51.31274, 12.41275,
+51.31272, 12.41270,
+51.31276, 12.41279,
+51.31285, 12.41296,
+51.31296, 12.41307,
+51.31305, 12.41318,
+51.31309, 12.41302,
+51.31298, 12.41302,
+51.31301, 12.41301,
+51.31299, 12.41297,
+51.31302, 12.41302,
+51.31298, 12.41320,
+51.31306, 12.41312,
+51.31298, 12.41302,
+51.31290, 12.41297,
+51.31285, 12.41296,
+51.31280, 12.41294,
+51.31250, 12.41312,
+51.31246, 12.41288,
+51.31275, 12.41253,
+51.31296, 12.41317,
+51.31288, 12.41324,
+51.31286, 12.41324,
+51.31282, 12.41331,
+51.31284, 12.41328,
+51.31283, 12.41331,
+51.31279, 12.41334,
+51.31278, 12.41333,
+51.31276, 12.41334,
+51.31282, 12.41332,
+51.31292, 12.41344,
+51.31299, 12.41379,
+51.31304, 12.41381,
+51.31305, 12.41384,
+51.31311, 12.41385,
+51.31321, 12.41388,
+51.31329, 12.41397,
+51.31329, 12.41405,
+51.31327, 12.41410,
+51.31304, 12.41461,
+51.31298, 12.41483,
+51.31293, 12.41494,
+51.31295, 12.41497,
+51.31293, 12.41498,
+51.31296, 12.41495,
+51.31317, 12.41459,
+51.31317, 12.41457,
+51.31316, 12.41444,
+51.31316, 12.41439,
+51.31334, 12.41391,
+51.31371, 12.41332,
+51.31399, 12.41286,
+51.31422, 12.41249,
+51.31465, 12.40956,
+51.31465, 12.40949,
+51.31465, 12.40949,
+51.31465, 12.40945,
+51.31464, 12.40936,
+51.31464, 12.40936,
+51.31464, 12.40936,
+51.31464, 12.40936,
+51.31464, 12.40936,
+51.31512, 12.41022,
+51.31517, 12.41034,
+51.31509, 12.41022,
+51.31506, 12.41031,
+51.31496, 12.41036,
+51.31485, 12.40939,
+51.31484, 12.40938,
+51.31484, 12.40945,
+51.31486, 12.40930,
+51.31412, 12.40669,
+51.31396, 12.40623,
+51.31370, 12.40579,
+51.31334, 12.40497,
+51.31270, 12.40350,
+51.31221, 12.40235,
+51.31185, 12.40145,
+51.31140, 12.40011,
+51.31101, 12.39885,
+51.31066, 12.39779,
+51.31050, 12.39728,
+51.31043, 12.39698,
+51.30961, 12.39358,
+51.30946, 12.39236,
+51.30931, 12.39060,
+51.30924, 12.38872,
+51.30928, 12.38751,
+51.30943, 12.38620,
+51.30962, 12.38478,
+51.30985, 12.38313,
+51.31010, 12.38143,
+51.31024, 12.38029,
+51.31027, 12.37932,
+51.31032, 12.37870,
+51.31038, 12.37778,
+51.31048, 12.37646,
+51.31060, 12.37526,
+51.31068, 12.37448,
+51.31072, 12.37411,
+51.30883, 12.37343,
+51.30854, 12.37345,
+51.30777, 12.37349,
+51.30718, 12.37357,
+51.30658, 12.37362,
+51.30542, 12.37378,
+51.30472, 12.37395,
+51.30380, 12.37424,
+51.30322, 12.37419,
+51.30267, 12.37387,
+51.30224, 12.37362,
+51.30188, 12.37324,
+51.30178, 12.37309,
+51.30161, 12.37265,
+51.30170, 12.37224,
+51.30179, 12.37179,
+51.30206, 12.37150,
+51.30223, 12.37154,
+51.30242, 12.37171,
+51.30243, 12.37208,
+51.30226, 12.37251,
+51.30161, 12.37379,
+51.30097, 12.37475,
+51.30044, 12.37540,
+51.29965, 12.37603,
+51.29877, 12.37646,
+51.29787, 12.37656,
+51.29688, 12.37664,
+51.29528, 12.37674,
+51.29335, 12.37755,
+51.29225, 12.37790,
+51.29114, 12.37803,
+51.28943, 12.37808,
+51.28728, 12.37854,
+51.28639, 12.37917,
+51.28505, 12.38029,
+51.28343, 12.38171,
+51.28219, 12.38266,
+51.28127, 12.38312,
+51.28032, 12.38329,
+51.27890, 12.38341,
+51.27738, 12.38336,
+51.27595, 12.38314,
+51.27460, 12.38279,
+51.27271, 12.38222,
+51.27198, 12.38200,
+51.27083, 12.38165,
+51.26981, 12.38146,
+51.26827, 12.38132,
+51.26680, 12.38136,
+51.26530, 12.38163,
+51.26381, 12.38204,
+51.26292, 12.38230,
+51.26111, 12.38289,
+51.26060, 12.38306,
+51.25979, 12.38326,
+51.25847, 12.38358,
+51.25635, 12.38404,
+51.25462, 12.38438,
+51.25299, 12.38462,
+51.25178, 12.38484,
+51.25046, 12.38514,
+51.24874, 12.38572,
+51.24735, 12.38627,
+51.24566, 12.38703,
+51.24378, 12.38776,
+51.24205, 12.38833,
+51.24094, 12.38848,
+51.24035, 12.38856,
+51.23932, 12.38862,
+51.23828, 12.38861,
+51.23688, 12.38859,
+51.23538, 12.38857,
+51.23290, 12.38852,
+51.23119, 12.38835,
+51.23028, 12.38822,
+51.22924, 12.38808,
+51.22801, 12.38798,
+51.22402, 12.38775,
+51.22241, 12.38767,
+51.22061, 12.38760,
+51.21923, 12.38760,
+51.21784, 12.38787,
+51.21672, 12.38832,
+51.21544, 12.38914,
+51.21442, 12.39003,
+51.21347, 12.39113,
+51.21263, 12.39234,
+51.21179, 12.39392,
+51.21103, 12.39570,
+51.20998, 12.39856,
+51.20837, 12.40303,
+51.20728, 12.40607,
+51.20622, 12.40904,
+51.20511, 12.41198,
+51.20408, 12.41444,
+51.20304, 12.41667,
+51.20178, 12.41929,
+51.20052, 12.42208,
+51.20007, 12.42366,
+51.19955, 12.42597,
+51.19889, 12.42878,
+51.19794, 12.43220,
+51.19710, 12.43514,
+51.19641, 12.43786,
+51.19613, 12.43967,
+51.19604, 12.44114,
+51.19611, 12.44297,
+51.19629, 12.44543,
+51.19652, 12.44853,
+51.19649, 12.45027,
+51.19624, 12.45172,
+51.19587, 12.45351,
+51.19534, 12.45619,
+51.19509, 12.45764,
+51.19467, 12.46005,
+51.19422, 12.46184,
+51.19378, 12.46312,
+51.19322, 12.46464,
+51.19259, 12.46635,
+51.19206, 12.46768,
+51.19129, 12.46952,
+51.19051, 12.47131,
+51.18976, 12.47302,
+51.18881, 12.47520,
+51.18831, 12.47632,
+51.18772, 12.47736,
+51.18722, 12.47796,
+51.18630, 12.47869,
+51.18520, 12.47960,
+51.18455, 12.48015,
+51.18388, 12.48072,
+51.18320, 12.48129,
+51.18213, 12.48221,
+51.18114, 12.48306,
+51.18011, 12.48393,
+51.17862, 12.48528,
+51.17711, 12.48665,
+51.17544, 12.48820,
+51.17471, 12.48888,
+51.17336, 12.49012,
+51.17185, 12.49153,
+51.17009, 12.49316,
+51.16809, 12.49501,
+51.16676, 12.49625,
+51.16529, 12.49762,
+51.16389, 12.49892,
+51.16195, 12.50074,
+51.15981, 12.50286,
+51.15812, 12.50470,
+51.15636, 12.50680,
+51.15567, 12.50746,
+51.15507, 12.50786,
+51.15428, 12.50815,
+51.15340, 12.50844,
+51.15246, 12.50872,
+51.15185, 12.50891,
+51.15115, 12.50915,
+51.15013, 12.50946,
+51.14901, 12.50965,
+51.14794, 12.50969,
+51.14700, 12.50972,
+51.14537, 12.50987,
+51.14380, 12.50999,
+51.14265, 12.51008,
+51.14102, 12.51003,
+51.14007, 12.50992,
+51.13942, 12.50984,
+51.13862, 12.50975,
+51.13799, 12.50955,
+51.13772, 12.50943,
+51.13750, 12.50929,
+51.13739, 12.50922,
+51.13694, 12.50894,
+51.13682, 12.50886,
+51.13608, 12.50837,
+51.13550, 12.50798,
+51.13441, 12.50725,
+51.13326, 12.50647,
+51.13245, 12.50600,
+51.13152, 12.50563,
+51.13032, 12.50517,
+51.12969, 12.50497,
+51.12894, 12.50471,
+51.12822, 12.50450,
+51.12693, 12.50178,
+51.12656, 12.50063,
+51.12630, 12.49978,
+51.12614, 12.49874,
+51.12601, 12.49745,
+51.12578, 12.49588,
+51.12546, 12.49462,
+51.12506, 12.49352,
+51.12446, 12.49225,
+51.12382, 12.49121,
+51.12281, 12.48996,
+51.12245, 12.48951,
+51.12201, 12.48900,
+51.12141, 12.48836,
+51.12105, 12.48797,
+51.12077, 12.48739,
+51.12072, 12.48720,
+51.12029, 12.48563,
+51.11970, 12.48428,
+51.11935, 12.48401,
+51.11906, 12.48407,
+51.11886, 12.48418,
+51.11790, 12.48487,
+51.11742, 12.48522,
+51.11675, 12.48575,
+51.11627, 12.48616,
+51.11543, 12.48687,
+51.11463, 12.48756,
+51.11371, 12.48825,
+51.11333, 12.48853,
+51.11301, 12.48877,
+51.11276, 12.48896,
+51.11248, 12.48917,
+51.11212, 12.48957,
+51.11156, 12.49029,
+51.11097, 12.49098,
+51.11060, 12.49114,
+51.11046, 12.49116,
+51.10966, 12.49109,
+51.10883, 12.49082,
+51.10813, 12.49034,
+51.10742, 12.48967,
+51.10680, 12.48888,
+51.10606, 12.48784,
+51.10529, 12.48676,
+51.10461, 12.48581,
+51.10361, 12.48441,
+51.10273, 12.48302,
+51.10208, 12.48161,
+51.10131, 12.47986,
+51.10064, 12.47888,
+51.09990, 12.47809,
+51.09887, 12.47730,
+51.09691, 12.47601,
+51.09526, 12.47491,
+51.09426, 12.47418,
+51.09345, 12.47320,
+51.09260, 12.47237,
+51.09185, 12.47178,
+51.09107, 12.47117,
+51.09021, 12.47046,
+51.08925, 12.46975,
+51.08836, 12.46926,
+51.08718, 12.46866,
+51.08609, 12.46826,
+51.08453, 12.46767,
+51.08360, 12.46700,
+51.08170, 12.46562,
+51.08137, 12.46543,
+51.08043, 12.46511,
+51.07919, 12.46482,
+51.07797, 12.46453,
+51.07690, 12.46425,
+51.07575, 12.46396,
+51.07501, 12.46359,
+51.07438, 12.46310,
+51.07392, 12.46250,
+51.07331, 12.46164,
+51.07288, 12.46106,
+51.07242, 12.46039,
+51.07172, 12.45942,
+51.07029, 12.45744,
+51.06939, 12.45619,
+51.06787, 12.45409,
+51.06758, 12.45381,
+51.06701, 12.45350,
+51.06672, 12.45348,
+51.06579, 12.45346,
+51.06486, 12.45355,
+51.06436, 12.45375,
+51.06362, 12.45399,
+51.06280, 12.45405,
+51.06258, 12.45406,
+51.06215, 12.45384,
+51.06178, 12.45348,
+51.06146, 12.45347,
+51.06134, 12.45352,
+51.06047, 12.45388,
+51.05968, 12.45420,
+51.05830, 12.45477,
+51.05796, 12.45488,
+51.05727, 12.45477,
+51.05630, 12.45439,
+51.05493, 12.45386,
+51.05454, 12.45372,
+51.05403, 12.45349,
+51.05338, 12.45317,
+51.05332, 12.45316,
+51.05292, 12.45322,
+51.05190, 12.45364,
+51.05060, 12.45420,
+51.04975, 12.45444,
+51.04888, 12.45471,
+51.04741, 12.45519,
+51.04662, 12.45540,
+51.04585, 12.45539,
+51.04422, 12.45532,
+51.04308, 12.45536,
+51.04232, 12.45568,
+51.04161, 12.45632,
+51.04058, 12.45735,
+51.03970, 12.45789,
+51.03872, 12.45824,
+51.03732, 12.45865,
+51.03579, 12.45888,
+51.03481, 12.45888,
+51.03388, 12.45861,
+51.03243, 12.45809,
+51.03149, 12.45800,
+51.02979, 12.45810,
+51.02916, 12.45811,
+51.02856, 12.45809,
+51.02759, 12.45810,
+51.02663, 12.45809,
+51.02572, 12.45786,
+51.02479, 12.45750,
+51.02387, 12.45689,
+51.02193, 12.45524,
+51.02099, 12.45475,
+51.02003, 12.45462,
+51.01878, 12.45447,
+51.01789, 12.45437,
+51.01689, 12.45425,
+51.01572, 12.45412,
+51.01468, 12.45400,
+51.01351, 12.45401,
+51.01261, 12.45425,
+51.01166, 12.45473,
+51.01079, 12.45543,
+51.01000, 12.45641,
+51.00914, 12.45752,
+51.00788, 12.45894,
+51.00639, 12.46046,
+51.00569, 12.46139,
+51.00515, 12.46239,
+51.00455, 12.46373,
+51.00349, 12.46626,
+51.00280, 12.46756,
+51.00200, 12.46865,
+51.00113, 12.46955,
+51.00010, 12.47027,
+50.99898, 12.47072,
+50.99813, 12.47089,
+50.99709, 12.47091,
+50.99606, 12.47064,
+50.99497, 12.47020,
+50.99298, 12.46923,
+50.99114, 12.46834,
+50.98960, 12.46759,
+50.98795, 12.46679,
+50.98599, 12.46599,
+50.98478, 12.46568,
+50.98336, 12.46564,
+50.98183, 12.46559,
+50.98029, 12.46536,
+50.97898, 12.46487,
+50.97768, 12.46409,
+50.97651, 12.46313,
+50.97544, 12.46200,
+50.97445, 12.46063,
+50.97356, 12.45901,
+50.97278, 12.45729,
+50.97154, 12.45396,
+50.97015, 12.45028,
+50.96886, 12.44684,
+50.96773, 12.44382,
+50.96609, 12.43942,
+50.96487, 12.43614,
+50.96441, 12.43462,
+50.96408, 12.43325,
+50.96368, 12.43120,
+50.96339, 12.42902,
+50.96312, 12.42697,
+50.96269, 12.42394,
+50.96221, 12.42166,
+50.96158, 12.41949,
+50.96086, 12.41767,
+50.96003, 12.41584,
+50.95911, 12.41416,
+50.95835, 12.41302,
+50.95763, 12.41208,
+50.95670, 12.41101,
+50.95561, 12.41004,
+50.95454, 12.40919,
+50.95298, 12.40808,
+50.95177, 12.40728,
+50.95030, 12.40625,
+50.94977, 12.40583,
+50.94880, 12.40501,
+50.94818, 12.40448,
+50.94725, 12.40368,
+50.94652, 12.40305,
+50.94566, 12.40232,
+50.94452, 12.40138,
+50.94389, 12.40086,
+50.94268, 12.39994,
+50.94166, 12.39920,
+50.94114, 12.39902,
+50.94116, 12.39911,
+50.94148, 12.39995,
+50.94205, 12.40134,
+50.94238, 12.40234,
+50.94258, 12.40331,
+50.94270, 12.40416,
+50.94284, 12.40604,
+50.94295, 12.40750,
+50.94289, 12.40862,
+50.94282, 12.41003,
+50.94280, 12.41110,
+50.94276, 12.41193,
+50.94270, 12.41220,
+50.94248, 12.41254,
+50.94172, 12.41331,
+50.94120, 12.41378,
+50.94091, 12.41392,
+50.94049, 12.41396,
+50.94017, 12.41403,
+50.93989, 12.41409,
+50.93948, 12.41441,
+50.93908, 12.41473,
+50.93859, 12.41478,
+50.93795, 12.41471,
+50.93730, 12.41467,
+50.93648, 12.41495,
+50.93597, 12.41516,
+50.93535, 12.41545,
+50.93492, 12.41583,
+50.93448, 12.41640,
+50.93441, 12.41649,
+50.93396, 12.41687,
+50.93372, 12.41728,
+50.93370, 12.41752,
+50.93367, 12.41811,
+50.93368, 12.41818,
+50.93373, 12.41847,
+50.93378, 12.41880,
+50.93375, 12.41929,
+50.93373, 12.41937,
+50.93359, 12.41977,
+50.93331, 12.42035,
+50.93312, 12.42074,
+50.93309, 12.42075,
+50.93289, 12.42087,
+50.93231, 12.42119,
+50.93179, 12.42153,
+50.93146, 12.42193,
+50.93111, 12.42231,
+50.93065, 12.42248,
+50.93057, 12.42248,
+50.93021, 12.42231,
+50.93013, 12.42227,
+50.92986, 12.42243,
+50.92969, 12.42273,
+50.92943, 12.42347,
+50.92898, 12.42415,
+50.92869, 12.42456,
+50.92838, 12.42498,
+50.92810, 12.42539,
+50.92743, 12.42637,
+50.92732, 12.42654,
+50.92714, 12.42657,
+50.92711, 12.42657,
+50.92688, 12.42664,
+50.92677, 12.42696,
+50.92649, 12.42758,
+50.92603, 12.42820,
+50.92523, 12.42912,
+50.92435, 12.43008,
+50.92374, 12.43058,
+50.92326, 12.43098,
+50.92292, 12.43125,
+50.92262, 12.43150,
+50.92218, 12.43201,
+50.92196, 12.43229,
+50.92186, 12.43241,
+50.92181, 12.43263,
+50.92190, 12.43281,
+50.92216, 12.43338,
+50.92235, 12.43440,
+50.92236, 12.43454,
+50.92242, 12.43524,
+50.92245, 12.43580,
+50.92241, 12.43635,
+50.92228, 12.43684,
+50.92213, 12.43764,
+50.92210, 12.43856,
+50.92210, 12.43897,
+50.92197, 12.43961,
+50.92189, 12.43973,
+50.92133, 12.44067,
+50.92090, 12.44099,
+50.92061, 12.44111,
+50.92019, 12.44160,
+50.92009, 12.44210,
+50.92009, 12.44231,
+50.92013, 12.44295,
+50.92021, 12.44361,
+50.92021, 12.44414,
+50.92014, 12.44459,
+50.92009, 12.44496,
+50.91991, 12.44493,
+50.91939, 12.44478,
+50.91881, 12.44461,
+50.91795, 12.44436,
+50.91728, 12.44416,
+50.91625, 12.44385,
+50.91494, 12.44347,
+50.91432, 12.44328,
+50.91345, 12.44303,
+50.91240, 12.44271,
+50.91163, 12.44253,
+50.91119, 12.44245,
+50.91085, 12.44223,
+50.91050, 12.44187,
+50.91008, 12.44164,
+50.90939, 12.44138,
+50.90855, 12.44106,
+50.90763, 12.44073,
+50.90686, 12.44045,
+50.90550, 12.43996,
+50.90494, 12.44001,
+50.90390, 12.44021,
+50.90279, 12.44043,
+50.90157, 12.44073,
+50.90086, 12.44077,
+50.90012, 12.44047,
+50.89959, 12.44005,
+50.89912, 12.43932,
+50.89875, 12.43875,
+50.89830, 12.43820,
+50.89739, 12.43721,
+50.89642, 12.43616,
+50.89566, 12.43536,
+50.89516, 12.43498,
+50.89432, 12.43453,
+50.89349, 12.43410,
+50.89271, 12.43371,
+50.89191, 12.43344,
+50.89107, 12.43352,
+50.89058, 12.43357,
+50.89023, 12.43362,
+50.88976, 12.43370,
+50.88908, 12.43386,
+50.88864, 12.43399,
+50.88850, 12.43378,
+50.88849, 12.43367,
+50.88836, 12.43254,
+50.88834, 12.43240,
+50.88824, 12.43202,
+50.88780, 12.43101,
+50.88753, 12.43078,
+50.88726, 12.43086,
+50.88671, 12.43103,
+50.88612, 12.43096,
+50.88539, 12.43067,
+50.88531, 12.43065,
+50.88507, 12.43064,
+50.88454, 12.43036,
+50.88417, 12.43014,
+50.88369, 12.43012,
+50.88323, 12.43046,
+50.88294, 12.43066,
+50.88220, 12.43101,
+50.88210, 12.43108,
+50.88155, 12.43163,
+50.88090, 12.43223,
+50.88027, 12.43262,
+50.87958, 12.43292,
+50.87884, 12.43323,
+50.87812, 12.43355,
+50.87732, 12.43390,
+50.87664, 12.43432,
+50.87581, 12.43486,
+50.87536, 12.43516,
+50.87470, 12.43513,
+50.87404, 12.43503,
+50.87316, 12.43481,
+50.87260, 12.43466,
+50.87216, 12.43434,
+50.87206, 12.43421,
+50.87135, 12.43340,
+50.87061, 12.43275,
+50.86996, 12.43206,
+50.86941, 12.43147,
+50.86822, 12.43046,
+50.86718, 12.42966,
+50.86636, 12.42927,
+50.86571, 12.42912,
+50.86482, 12.42906,
+50.86414, 12.42902,
+50.86351, 12.42868,
+50.86246, 12.42812,
+50.86172, 12.42779,
+50.86097, 12.42736,
+50.86039, 12.42687,
+50.85994, 12.42654,
+50.85980, 12.42648,
+50.85949, 12.42649,
+50.85917, 12.42658,
+50.85879, 12.42640,
+50.85872, 12.42619,
+50.85853, 12.42520,
+50.85847, 12.42485,
+50.85831, 12.42450,
+50.85804, 12.42447,
+50.85794, 12.42424,
+50.85794, 12.42377,
+50.85799, 12.42333,
+50.85811, 12.42258,
+50.85822, 12.42165,
+50.85817, 12.42106,
+50.85804, 12.42088,
+50.85768, 12.42042,
+50.85765, 12.42036,
+50.85750, 12.41992,
+50.85747, 12.41912,
+50.85748, 12.41859,
+50.85749, 12.41841,
+50.85750, 12.41818,
+50.85751, 12.41791,
+50.85751, 12.41780,
+50.85771, 12.41791,
+50.85771, 12.41796,
+50.85771, 12.41797,
+50.85779, 12.41793,
+50.85772, 12.41785,
+50.85778, 12.41797,
+50.85770, 12.41784,
+50.85777, 12.41791,
+50.85778, 12.41794,
+50.85778, 12.41796,
gpsbabel -i geo -f ${REFERENCE}/geocaching.loc -o geo -F ${TMPDIR}/gl.loc
compare ${TMPDIR}/gl.loc ${REFERENCE}
+# try with positional arugments
+rm -f ${TMPDIR}/gl.loc
+gpsbabel -i geo -o geo ${REFERENCE}/geocaching.loc ${TMPDIR}/gl.loc
+compare ${TMPDIR}/gl.loc ${REFERENCE}
+
# we have a one off reader in geo, make sure it can read stdin.
rm -f ${TMPDIR}/gl_si.loc
cat ${REFERENCE}/geocaching.loc | gpsbabel -i geo -f - -o geo -F ${TMPDIR}/gl_si.loc
gpsbabel -i iblue747 -f ${REFERENCE}/track/iblue747.csv -o gpx -F ${TMPDIR}/iblue747~csv.gpx
compare ${REFERENCE}/track/iblue747~csv.gpx ${TMPDIR}/iblue747~csv.gpx
+gpsbabel -i iblue747 -o csv -f ${REFERENCE}/track/iblue747.csv -F ${TMPDIR}/iblue747~csv.csv
+compare ${REFERENCE}/track/iblue747~csv.csv ${TMPDIR}/iblue747~csv.csv
+
#include <algorithm> // for sort
#include <cassert> // for assert
#include <cstdio> // for printf, putchar, sscanf
+#include <type_traits> // for add_const<>::type, is_base_of
#include "defs.h" // for arglist_t, ff_vecs_t, ff_cap, fatal, CSTR, ARGTYPE_TYPEMASK, case_ignore_strcmp, global_options, global_opts, warning, xfree, ARGTYPE_BOOL, ff_cap_read, ff_cap_write, ARGTYPE_HIDDEN, ff_type_internal, xstrdup, ARGTYPE_INT, ARGTYPE_REQUIRED, ARGTYPE_FLOAT
#include "dg-100.h" // for Dg100FileFormat, Dg100SerialFormat, Dg200FileFormat, Dg200SerialFormat
#define MYNAME "vecs"
+template <typename T>
+Format* fmtfactory(const QString& filename)
+{
+ static_assert(std::is_base_of<Format, T>::value, "T must be derived from Format");
+ return new T(filename);
+}
+
struct Vecs::Impl {
/*
* Having these LegacyFormat instances be non-static data members
* instance is guaranteed to have already constructed when an instance
* of this class is constructed.
*/
-#if CSVFMTS_ENABLED
- XcsvFormat xcsv_fmt;
-#endif // CSVFMTS_ENABLED
- GeoFormat geo_fmt;
GpxFormat gpx_fmt;
LegacyFormat garmin_fmt {garmin_vecs};
GdbFormat gdb_fmt;
#if CSVFMTS_ENABLED
/* XCSV must be the first entry in this table. */
{
- &xcsv_fmt,
+ nullptr,
"xcsv",
"? Character Separated Values",
nullptr,
nullptr,
+ &fmtfactory<XcsvFormat>
},
#endif
{
- &geo_fmt,
+ nullptr,
"geo",
"Geocaching.com .loc",
"loc",
nullptr,
+ &fmtfactory<GeoFormat>
},
{
&gpx_fmt,
* the default the default constructor would be implicitly deleted.
*/
+void Vecs::init_vec(Format* fmt)
+{
+ QVector<arglist_t>* args = fmt->get_args();
+ if (args && !args->isEmpty()) {
+ assert(args->isDetached());
+ for (auto& arg : *args) {
+ arg.argvalptr = nullptr;
+ if (arg.argval) {
+ *arg.argval = nullptr;
+ }
+ }
+ }
+}
+
void Vecs::init_vecs()
{
for (const auto& vec : d_ptr_->vec_list) {
- QVector<arglist_t>* args = vec.vec->get_args();
- if (args && !args->isEmpty()) {
- assert(args->isDetached());
- for (auto& arg : *args) {
- arg.argvalptr = nullptr;
- if (arg.argval) {
- *arg.argval = nullptr;
- }
- }
+ if (vec.vec != nullptr) {
+ init_vec(vec.vec);
}
}
style_list = create_style_vec();
(!val.isEmpty() && val.at(0).isDigit());
}
+void Vecs::exit_vec(Format* fmt)
+{
+ (fmt->exit)();
+ QVector<arglist_t>* args = fmt->get_args();
+ if (args && !args->isEmpty()) {
+ assert(args->isDetached());
+ for (auto& arg : *args) {
+ if (arg.argvalptr) {
+ xfree(arg.argvalptr);
+ *arg.argval = arg.argvalptr = nullptr;
+ }
+ }
+ }
+}
+
void Vecs::exit_vecs()
{
for (const auto& vec : d_ptr_->vec_list) {
- (vec.vec->exit)();
- QVector<arglist_t>* args = vec.vec->get_args();
- if (args && !args->isEmpty()) {
- assert(args->isDetached());
- for (auto& arg : *args) {
- if (arg.argvalptr) {
- xfree(arg.argvalptr);
- *arg.argval = arg.argvalptr = nullptr;
- }
- }
+ if (vec.vec != nullptr) {
+ exit_vec(vec.vec);
}
}
style_list.clear();
}
}
-void Vecs::prepare_format(const fmtinfo_t& fmtdata) const
+void Vecs::prepare_format(const fmtinfo_t& fmtdata)
{
QVector<arglist_t>* args = fmtdata->get_args();
* that we are processing xcsv,style= and it was preceeded by an xcsv
* format that utilized an internal style file.
*/
- d_ptr_->xcsv_fmt.xcsv_setup_internal_style(fmtdata.style_filename);
+ auto* xcsvfmt = dynamic_cast<XcsvFormat*>(fmtdata.fmt);
+ if (xcsvfmt != nullptr) {
+ xcsvfmt->xcsv_setup_internal_style(fmtdata.style_filename);
+ }
#endif // CSVFMTS_ENABLED
}
continue;
}
- fmtinfo_t fmtinfo{vec.vec, vec.name, nullptr, options};
- prepare_format(fmtinfo);
- return fmtinfo;
+ return {vec.vec, vec.name, nullptr, options, vec.factory};
}
/*
continue;
}
- fmtinfo_t fmtinfo{d_ptr_->vec_list.at(0).vec, svec.name, svec.style_filename, options};
- prepare_format(fmtinfo);
- return fmtinfo;
+ return {d_ptr_->vec_list.at(0).vec, svec.name, svec.style_filename, options, d_ptr_->vec_list.at(0).factory};
}
/*
/* Gather relevant information for normal formats. */
for (const auto& vec : d_ptr_->vec_list) {
+ Format* fmt = (vec.factory != nullptr)? vec.factory("") : vec.vec;
vecinfo_t info;
info.name = vec.name;
info.desc = vec.desc;
} else {
info.parent = vec.parent;
}
- info.type = vec.vec->get_type();
- info.cap = vec.vec->get_cap();
- const QVector<arglist_t>* args = vec.vec->get_args();
+ info.type = fmt->get_type();
+ info.cap = fmt->get_cap();
+ const QVector<arglist_t>* args = fmt->get_args();
if (args != nullptr) {
for (const auto& arg : *args) {
info.arginfo.append(arginfo_t(arg));
}
}
svp.append(info);
+ if (vec.factory != nullptr) {
+ delete fmt;
+ }
}
#if CSVFMTS_ENABLED
* Make sure we know which entry in the vector list that is.
*/
assert(d_ptr_->vec_list.at(0).name.compare("xcsv", Qt::CaseInsensitive) == 0);
+
+ Format* xcsvfmt = (d_ptr_->vec_list.at(0).factory != nullptr)? d_ptr_->vec_list.at(0).factory("") : d_ptr_->vec_list.at(0).vec;
/* The style formats use a modified xcsv argument list that doesn't include
* the option to set the style file. Make sure we know which entry in
* the argument list that is.
*/
- assert(case_ignore_strcmp(d_ptr_->vec_list.at(0).vec->get_args()->at(0).helpstring,
+ assert(case_ignore_strcmp(xcsvfmt->get_args()->at(0).helpstring,
"Full path to XCSV style file") == 0);
/* Gather the relevant info for the style based formats. */
* 'Full path to XCSV style file' argument to any
* GUIs for an internal format.
*/
- const QVector<arglist_t>* args = d_ptr_->vec_list.at(0).vec->get_args();
+ const QVector<arglist_t>* args = xcsvfmt->get_args();
if (args != nullptr) {
bool first = true;
for (const auto& arg : *args) {
}
svp.append(info);
}
+ if (d_ptr_->vec_list.at(0).factory != nullptr) {
+ delete xcsvfmt;
+ }
#endif // CSVFMTS_ENABLED
/*
bool Vecs::validate_vec(const vecs_t& vec)
{
- bool ok = validate_args(vec.name, vec.vec->get_args());
+ Format* fmt = (vec.factory != nullptr)? vec.factory("") : vec.vec;
+ bool ok = validate_args(vec.name, fmt->get_args());
+ if (vec.factory != nullptr) {
+ delete fmt;
+ }
return ok;
}
#ifndef VECS_H_INCLUDED_
#define VECS_H_INCLUDED_
-#include <cstdint> // for uint32_t
+#include <cstdint> // for uint32_t
-#include <QString> // for QString
-#include <QStringList> // for QStringList
-#include <QVector> // for QVector<>::iterator, QVector
+#include <QList> // for QList
+#include <QString> // for QString
+#include <QStringList> // for QStringList
+#include <QVector> // for QVector<>::iterator, QVector
#include "defs.h"
#include "format.h"
/* Types */
+ using FormatFactory = Format* (*)(const QString&);
+
class fmtinfo_t {
public:
+ bool isDynamic() {
+ return factory != nullptr;
+ }
explicit operator bool() const {
- return fmt != nullptr;
+ return ((fmt != nullptr) || (factory != nullptr));
}
Format* operator->() const {
return fmt;
}
- Format* fmt{};
+ Format* fmt{nullptr};
QString fmtname;
QString style_filename;
QStringList options;
+ FormatFactory factory{nullptr};
};
/* Special Member Functions */
/* Member Functions */
+ static void init_vec(Format* fmt);
void init_vecs();
+ static void exit_vec(Format* fmt);
void exit_vecs();
static void assign_option(const QString& module, arglist_t* arg, const QString& val);
static void disp_vec_options(const QString& vecname, const QVector<arglist_t>* args);
static void validate_options(const QStringList& options, const QVector<arglist_t>* args, const QString& name);
static QString get_option(const QStringList& options, const QString& argname);
- void prepare_format(const fmtinfo_t& data) const;
+ static void prepare_format(const fmtinfo_t& data) ;
fmtinfo_t find_vec(const QString& fmtargstring);
void disp_vecs() const;
void disp_vec(const QString& vecname) const;
QString desc;
QString extensions; // list of possible extensions separated by '/', first is output default for GUI.
QString parent;
+ FormatFactory factory{nullptr};
};
struct arginfo_t {
class XcsvFormat : public Format
{
public:
+ using Format::Format;
/* Member Functions */
QVector<arglist_t>* get_args() override
{